<?php
/**
 * Created by PhpStorm.
 * User: admin@zhangp.cn
 * Date: 2018-12-27
 * Time: 15:30
 */

namespace App\Models;


use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Mockery\Exception;
use phpDocumentor\Reflection\Types\Mixed_;

/**
 * 功能：所有模型的基类
 * Class BaseModel
 * @package App\Models
 */
class BaseModel extends Model
{

    /**
     * 功能：创建错误信息
     * @var string
     */
    static protected $error = '';

    /**
     * 功能:获取错误信息
     * @return string
     */
    static public function getErr()
    {
        return static::$error;
    }

    /**
     * 功能:设置错误信息内容
     * @param $msg
     * @return bool
     */
    static protected function setErr($msg)
    {
        static::$error = $msg;
        return false;
    }

    /**
     * 功能:条件查询
     * @param array $param
     * @return array
     */
    static public function listByWhere($param = [])
    {
        /*条件初始化*/
        $where = isset($param['where']) ? $param['where'] : [];
        $whereIn = isset($param['whereIn']) ? $param['whereIn'] : [];
        $orderBy = isset($param['orderBy']) ? $param['orderBy'] : ['id desc'];
        $whereRaw = isset($param['whereRaw']) ? $param['whereRaw'] : '';
        $groupBy = isset($param['groupBy']) ? $param['groupBy'] : [];
        $field = isset($param['field']) ? $param['field'] : ['*'];
        $with = isset($param['with']) ? $param['with'] : [];
        $whereHas = isset($param['whereHas']) ? $param['whereHas'] : [];
        $having = isset($param['having']) ? $param['having'] : [];
        array_key_exists('limit', $param) OR $param['limit'] = config('cdyz.pageSize');
        /*开始查询*/
        $res = self::select($field)
            ->where($where)
            // 原生sql查询
            ->when($whereRaw,function($query) use($whereRaw){
                foreach ($whereRaw as $item) {
                    $query->whereRaw($item);
                }
            })
            /*in查询*/
            ->when($whereIn, function ($query) use ($whereIn) {
                foreach ($whereIn as $k => $v) {
                    $query->whereIn($v[0], $v[1]);
                }
            })
            /*连表查询*/
            ->when($whereHas, function ($query) use ($whereHas) {
                foreach ($whereHas as $k => $v) {
                    $query->whereHas($v[0], $v[1]);
                }
            })
            /*关联查询*/
            ->when($with, function ($query) use ($with) {
                foreach ($with as $k => $v) {
                    $query->with($v);
                }
            })
            /*排序*/
            ->when($orderBy, function ($query) use ($orderBy) {
                foreach ($orderBy as $k => $v) {
                    $demo = explode(' ', $v);
                    $query->orderBy($demo[0], $demo[1]);
                }
            })
            /*分组*/
            ->when($groupBy, function ($query) use ($groupBy) {
                $query->groupBy($groupBy);
            })
            ->when($having,function($query)use($having){
                // 1 字段 2 条件 3 值
                foreach ($having as $key=>$item) {
                    $query->having($item[0],$item[1],$item[2]);
                }
            })
            ->paginate($param['limit'])
            ->toArray();
        return ['total' => $res['total'], 'list' => $res['data']];
    }

    /**
     * 启用禁用,几个端的用户使用
     * @param $id
     * @param string $img
     * @return bool|string
     */
    static public function changeStatus($id)
    {
        try {
            $row = self::where('user_id', $id)->first();
            if (empty($row)) throw new \Mockery\Exception("数据丢失");

            $status = $row->status == 0 ? 1 : 0;

            self::where('user_id', $id)->update(['status' => $status]);

            return "ok";
        } catch (\Exception $e) {
            self::setErr($e->getMessage());
            return false;
        }
    }

    /**
     * 查询所有
     * @param array $param
     * @return mixed
     */
    static public function getAll($param = [])
    {
        /*条件初始化*/
        $where = isset($param['where']) ? $param['where'] : [];
        $whereIn = isset($param['whereIn']) ? $param['whereIn'] : [];
        $orderBy = isset($param['orderBy']) ? $param['orderBy'] : ['id desc'];
        $groupBy = isset($param['groupBy']) ? $param['groupBy'] : [];
        $field = isset($param['field']) ? $param['field'] : ['*'];
        $with = isset($param['with']) ? $param['with'] : [];
        $whereHas = isset($param['whereHas']) ? $param['whereHas'] : [];
        $whereBetween = isset($param['whereBetween']) ? $param['whereBetween'] : [];
        $take = isset($param['take']) ? $param['take'] : 0;
        array_key_exists('pageSize', $param) OR $param['pageSize'] = config('rhzc.pageSize');
        $random = isset($param['random']) ? $param['random'] : false;
        /*开始查询*/
        $res = self::select($field)
            ->where($where)
            /*in查询*/
            ->when($whereIn, function ($query) use ($whereIn) {
                foreach ($whereIn as $k => $v) {
                    $query->whereIn($v[0], $v[1]);
                }
            })
            ->when($whereBetween, function ($query) use ($whereBetween) {
                foreach ($whereBetween as $k => $v) {
                    $query->whereBetween($v[0], $v[1]);
                }
            })
            /*关联查询*/
            ->when($with, function ($query) use ($with) {
                foreach ($with as $k => $v) {
                    $query->with($v);
                }
            })
            /*连表查询*/
            ->when($whereHas, function ($query) use ($whereHas) {
                foreach ($whereHas as $k => $v) {
                    $query->whereHas($v[0], $v[1]);
                }
            });
            if ($random == true) {
                $res = $res->inRandomOrder();
            }else{
                $res = $res->when($orderBy, function ($query) use ($orderBy) {///*排序*/
                    foreach ($orderBy as $k => $v) {
                        $demo = explode(' ', $v);
                        $query->orderBy($demo[0], $demo[1]);
                    }
                });
            }
            $res = $res->when($groupBy, function ($query) use ($groupBy) { // /*分组*/
                $query->groupBy($groupBy);
            });
            if ($take > 0 ){
                $res = $res->take($take);
            }
        $res = $res->get();
        return $res;
    }

    /**
     * 编辑
     * @param array $where 条件
     * @param array $field 字段
     * @return mixed
     */
    static function modify($where=array(),$field=array()){
        return self::where($where)->update($field);
    }

    /**
     * 获取详情
     * @param $where 条件
     * @return mixed
     */
    static public function detail($where){
        return self::where($where)->first();
    }

    /**
     * 功能:
     * @param $id
     * @param array $field
     * @return mixed
     */
    static public function getOne($id, $field = ['*'])
    {
        if (empty($id)) {
            self::setErr('缺少参数id');
            return false;
        }
        $res = self::select($field)
            ->where('id', $id)
            ->first();
        if (empty($res)) {
            self::setErr('目标不存在');
            return false;
        }
        return $res;
    }
    /**
     * 查询单条详情（可带关联）
     * @param $param
     * @return mixed
     */
    static public function detailsWith($param)
    {
        /*条件初始化*/
        $where = isset($param['where']) ? $param['where'] : [];
        $field = isset($param['field']) ? $param['field'] : ['*'];
        $with = isset($param['with']) ? $param['with'] : [];
        /*开始查询*/
        $res = self::select($field)
            ->where($where)
            /*关联查询*/
            ->when($with, function ($query) use ($with) {
                foreach ($with as $k => $v) {
                    $query->with($v);
                }
            })
            ->first();
        return $res;
    }

    /**
     * 功能:插入
     * @param $param
     * @return array|bool
     */
    static public function add($param)
    {
        try {
            $id = self::insertGetId($param);
            return ['id' => $id];
        } catch (\Exception  $e) {
            self::setErr($e->getMessage());
            return false;
        }
    }

    /**
     * 功能: 修改
     * @param $param
     * @return array|bool
     */
    static public function edit($param)
    {
        try {
            $obj = self::where('id', $param['id'])->first();

            if (!$obj) {
                self::setErr('目标不存在');
                return false;
            }
            self::where('id', $param['id'])->update($param);
            return 'ok';
        } catch (\Exception  $e) {
            self::setErr($e->getMessage());
            return false;
        }
    }

    /**
     * 功能:删除
     * @param $id
     * @param string $img
     * @return bool|string
     */
    static public function del($id, $img = '')
    {
        try {
            $row = self::where('id', $id)->first();
            if (empty($row)) throw new Exception("数据丢失");
            /*img表示图片字段名字，如果存在判断该图片是否有值，如果有则删除*/
            if ((isset($row->$img) && !empty($row->$img))) {
                @unlink('.' . $row->$img);
            }
            $row->delete();
            return "ok";
        } catch (\Exception $e) {
            self::setErr($e->getMessage());
            return false;
        }
    }


    /**
     * 功能:批量添加数据
     * @param array $data
     * @return mixed
     */
    static public function addAll(Array $data)
    {
        $rs = self::insert($data);
        return $rs;
    }

    /**
     * 功能:获得当前id下的所有子级Id
     * @param $id
     * @return array
     */
    static public function getChildren($id)
    {
        $data = self::get()->toArray();
        return _children($data, $id);
    }

    /**
     * 功能:获得当前id下的所有子级
     * @param int $id
     * @return array
     */
    static public function getChildrenTree($id = 0)
    {
        $data = self::get()->toArray();
        return getChild($data, $id);
    }


    /**
     * 功能: 排序加分页的树形结构
     * @param array $param
     * @return array
     */
    static public function getTreeList($param = [])
    {
        $where = isset($param['where']) ? $param['where'] : [];
        $field = isset($param['field']) ? $param['field'] : '*';
        array_key_exists('pageSize', $param) OR $param['pageSize'] = config('admin.pageSize');
        /*开始查询*/
        if (!array_key_exists('page', $param) && !array_key_exists('pageSize', $param)) {
            $param['pageSize'] =  99999;
        }
        array_key_exists('pageSize', $param) OR $param['pageSize'] = config('admin.pageSize');
        $res = self::select(DB::raw($field . ',concat(path,"-",id) AS paths'))
            ->orderBy('paths', 'asc')
            ->where($where)
            ->paginate($param['pageSize'])
            ->toArray();
        array_key_exists('p_id', $param) OR $param['p_id'] = 0;
        $res['data'] = _tree($res['data'], $param['p_id']);
        foreach ($res['data'] as &$v) {
            $v['name'] = str_repeat('&nbsp;&nbsp;&nbsp;┗━', $v['level']) . $v['name'];
        }
        unset($v);
        return ['total' => $res['total'], 'list' => $res['data']];
    }

    /**
     * 功能: 批量修改数据
     * @param array $multipleData
     * @return bool|int
     */
    public function updateAll($multipleData = [])
    {
        $tableName = config('database.connections.mysql.prefix') . $this->getTable();

        if ($tableName && !empty($multipleData)) {
            $multipleData = array_values($multipleData);
            //所有的字段名
            $updateColumn = array_keys($multipleData[0]);

            //字段的主键id
            $referenceColumn = $updateColumn[0]; //e.g id
            unset($updateColumn[0]);

            //whereIn条件 id的集合
            $whereIn = "";

            $q = "UPDATE " . $tableName . " SET ";
            foreach ($updateColumn as $uColumn) {
                $q .= "`" . $uColumn . "`" . " = CASE ";

                foreach ($multipleData as $data) {
                    //$referenceColumn为主键id，后为主键id的值，$uColumn为更改的字段名称，后为字段的更改值
                    $q .= "WHEN " . "`" . $referenceColumn . "`" . " = " . $data[$referenceColumn] . " THEN " . $data[$uColumn] . " ";
                }
                $q .= "ELSE " . "`" . $uColumn . "`" . " END, ";
            }
            foreach ($multipleData as $data) {
                $whereIn .= "'" . $data[$referenceColumn] . "', ";
            }
            $q = rtrim($q, ", ") . " WHERE " . "`" . $referenceColumn . "`" . " IN (" . rtrim($whereIn, ', ') . ")";

            // Update
            return DB::update(DB::raw($q));

        } else {
            return false;
        }

    }
}